#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include "String.hpp"
#include <string>

void TestString1()
{
	lw::string s;
	lw::string s1("hello world");
	s = s1;
	for (int i = 0; i < s.size(); i++)
	{
		std::cout << s[i];
	}
	std::cout << std::endl;

	s.resize(10);
	for (int i = 0; i < s.size(); i++)
	{
		std::cout << s[i];
	}
	std::cout << std::endl;

	s.resize(20, 'a');
	for (int i = 0; i < s.size(); i++)
	{
		std::cout << s[i];
	}
	std::cout << std::endl;
}

void TestString2()
{
	lw::string s;
	s.reserve(100);
	std::cout << s.capacity() << "   " << s.size() << std::endl;

	s += "hello world";
	std::cout << s.capacity() << "   " << s.size() << std::endl;
	for (auto ch : s)
		std::cout << ch;
	std::cout << std::endl;
	
	s += 'a';
	std::cout << s.capacity() << "   " << s.size() << std::endl;
	for (auto ch : s)
		std::cout << ch;
	std::cout << std::endl;
}

void TestString3()
{
	lw::string s("hello world");
	s.erase();
	for (auto ch : s)
		std::cout << ch;
	std::cout << std::endl;

}

void TestString4()
{
	lw::string s("hello world!!!");
	lw::string  tmp = s.substr(6);
	for (auto ch : tmp)
		std::cout << ch;
	std::cout << std::endl;

	std::cin >> tmp;
	std::cout << tmp;
}

//int main()
//{
//	TestString4();
//	return 0;
//}

template<class T>
bool Less(T a, T b)
{
	return a < b;
}

template<>
bool Less<int*>(int* a, int* b)
{
	return *a < *b;
}


//int main()
//{
//	int x = 10, y = 20;
//	std::cout << Less(2, 4) << std::endl;
//	std::cout << Less(x, y) << std::endl;
//	std::cout << Less(&x, &y) << std::endl;
//
//	return 0;
//}

template<class T1, class T2>
struct Data
{
	Data()
	{
		std::cout << "T1, T2" << std::endl;
	}
	//...
};

template<class T1, class T2>
struct Data<T1*, T2*>
{
	Data()
	{
		std::cout << "T1*, T2*" << std::endl;
	}
	//...
};

template<class T1, class T2>
struct Data<T1&, T2&>
{
	Data()
	{
		std::cout << "T1&, T2&" << std::endl;
	}
	// ...
};

//template<>
//struct Data<int, double>
//{
//	//...
//	Data()
//	{
//		std::cout << "int, double" << std::endl;
//	}
//};

//template<class T2>
//struct Data<int, T2>
//{
//	//...
//	Data()
//	{
//		std::cout << "int, T2" << std::endl;
//	}
//};
#include <algorithm>
#include "Vector.hpp"

void TestVector1()
{
	lw::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);

	lw::vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		std::cout << *it << ' ';
		it++;
	}
	std::cout << std::endl;

	v.resize(3);
	for (const auto& e : v)
		std::cout << e << ' ';
	std::cout << std::endl;

	v.resize(10, 123);
	for (const auto& e : v)
		std::cout << e << ' ';
	std::cout << std::endl;

	v.pop_back();
	v.pop_back();
	v.pop_back();
	for (const auto& e : v)
		std::cout << e << ' ';
	std::cout << std::endl;


}

void TestVector2()
{
	lw::vector<int> v;
	v.push_back(1);
	v.push_back(3);
	v.push_back(5);
	v.push_back(7);

	lw::vector<int>::iterator it = std::find(v.begin(), v.end(), 1);
	if (it != v.end())
	{
		v.insert(it, *it * 3);
	}
	for (const auto& e : v)
		std::cout << e << ' ';
	std::cout << std::endl;
}

void TestVector3()
{
	lw::vector<int> v;
	v.push_back(1);
	v.push_back(3);
	v.push_back(5);
	v.push_back(7);
	v.push_back(9);

	for (const auto& e : v)
		std::cout << e << " ";
	std::cout << std::endl;
	auto pos = std::find(v.begin(), v.end(), 3);
	/*v.erase(pos);
	for (const auto& e : v)
		std::cout << e << " ";
	std::cout << std::endl;*/

	v.erase(pos, v.end());
	for (const auto& e : v)
		std::cout << e << ' ';
	std::cout << std::endl;

	v.push_back(2);
	v.push_back(3);
	for (const auto& e : v)
		std::cout << e << ' ';
	std::cout << std::endl;


}

void TestVector4()
{
	lw::vector<int> v1;
	v1.push_back(1);
	v1.push_back(13);
	v1.push_back(143);

	lw::vector<int> v2(v1);
	for (const auto& e : v2)
		std::cout << e << ' ';
	std::cout << std::endl;

	v2.insert(v2.begin(), 100);
	v2.insert(v2.begin(), 1324);
	v2.insert(v2.begin(), 10345);

	v1 = v2;
	for (const auto& e : v1)
		std::cout << e << ' ';
	std::cout << std::endl;

}

#include "List.h"

//int main()
//{
//	TestVector4();
//
//
//	return 0;
//}

void TestList1()
{
	lw::list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	for (const auto& e : lt)
		std::cout << e << ' ';
	std::cout << std::endl;

	lt.push_front(10);
	lt.push_front(100);
	lt.push_front(1000);
	for (const auto& e : lt)
		std::cout << e << ' ';
	std::cout << std::endl;
	std::cout << lt.size() << std::endl;


	lt.pop_back();
	for (const auto& e : lt)
		std::cout << e << ' ';
	std::cout << std::endl;
	lt.pop_back();
	for (const auto& e : lt)
		std::cout << e << ' ';
	std::cout << std::endl;
	std::cout << lt.size() << std::endl;

	lt.pop_front();
	for (const auto& e : lt)
		std::cout << e << ' ';
	std::cout << std::endl;
	std::cout << lt.size() << std::endl;

	lt.pop_front();
	for (const auto& e : lt)
		std::cout << e << ' ';
	std::cout << std::endl;
	std::cout << lt.size() << std::endl;
}

void TestList2()
{
	lw::list<int> lt1;
	lt1.push_back(1);
	lt1.push_back(2);
	lt1.push_back(3);

	lw::list<int> lt2(lt1);
	for (const auto& e : lt2)
		std::cout << e << ' ';
	std::cout << std::endl;
	std::cout << lt2.size() << std::endl;

	lt2.push_front(10);
	lt2.push_front(20);
	lt2.push_front(30);
	lt2.pop_back();

	lt1 = lt2;
	for (const auto& e : lt1)
		std::cout << e << ' ';
	std::cout << std::endl;
	std::cout << lt1.size() << std::endl;


}


int main()
{
	TestList2();
	return 0;
}
